using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

namespace PowerfulExtensions.Helpers
{
    public class ByMembersEqualityComparer<TClass> : IEqualityComparer<TClass>
    {
        private readonly Expression<Func<TClass, object>>[] _expressions;

        public ByMembersEqualityComparer(params Expression<Func<TClass, object>>[] expressions)
        {
            _expressions = expressions;
        }

        public bool Equals(TClass x, TClass y)
        {
            if(!_expressions.Any())
                return object.Equals(x, y);                

            foreach (var expression in _expressions)
            {
                var exp = expression;

                var valueX = ExpressionHelper.GetValue(exp, x);
                var valueY = ExpressionHelper.GetValue(exp, y);

                if (!object.Equals(valueX, valueY))
                    return false;
            }

            return true;
        }

        public int GetHashCode(TClass obj)
        {
            if (object.Equals(default(TClass), obj))
            {
                return 0;
            }

            var hash = 0;
            foreach (var expression in _expressions)
            {
                var exp = expression;

                var value = ExpressionHelper.GetValue(exp, obj);
                if (value != null)
                    hash ^= value.GetHashCode();
            }

            return hash;
        }
    }
}